package xyz.hujf.bayes.test1;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;

/**
 * @author Hujf
 * @title: BayesTest
 * @date 2021-05-08 14:36
 * @description: 朴素贝叶斯算法   数据挖掘和推荐系统
 *
 * 准备工作阶段，任务是为朴素贝叶斯分类做必要的准备，
 * 主要工作是根据具体情况确定特征属性，并对每个特征属性进行适当划分，
 * 然后由人工对一部分待分类项进行分类，形成训练样本集合。
 * 这一阶段的输入是所有待分类数据，输出是特征属性和训练样本。
 * 这一阶段是整个朴素贝叶斯分类中唯一需要人工完成的阶段，
 * 其质量对整个过程将有重要影响，分类器的质量很大程度上由特征属性、特征属性划分及训练样本质量决定。
 *
 *
 * 分类器训练阶段。这个阶段的任务就是生成分类器，
 * 主要工作是计算每个类别在训练样本中的出现频率及每个特征属性划分对每个类别的条件概率估计，
 * 并将结果记录。其输入是特征属性和训练样本，输出是分类器。这一阶段是机械性阶段，
 * 根据前面讨论的公式可以由程序自动计算完成。
 *
 *
 * 应用阶段。这个阶段的任务是使用分类器对待分类项进行分类，
 * 其输入是分类器和待分类项，输出是待分类项与类别的映射关系。
 * 这一阶段也是机械性阶段，由程序完成。
 *
 */
public class NaiveBayesClassifier {

    //内部训练集
    private static ArrayList<JavaBean> datas = new ArrayList();

    //训练样本
    static int buy_yes=0;
    static int buy_no=0;

    static int num_age_yes=0;
    static int num_age_no=0;

    static int num_income_yes=0;
    static int num_income_no=0;

    static int num_student_yes=0;
    static int num_student_no =0;

    static int num_credit_yes=0;
    static int num_credit_no=0;


    static int data_length=0;


    public static void main(String[] args) {
        //获得datas
        getData();
        //根据你的输入来计算可能的输出
        testData(55,"Medium","Yes","Fair");


        System.out.println("购买的历史个数:"+buy_yes);
        System.out.println("不买的历史个数:"+buy_no);
        System.out.println("购买+age:"+num_age_yes);
        System.out.println("不买+age:"+num_age_no);
        System.out.println("购买+income:"+num_income_yes);
        System.out.println("不买+income:"+num_income_no);
        System.out.println("购买+stundent:"+num_student_yes);
        System.out.println("不买+student:"+ num_student_no);
        System.out.println("购买+credit:"+num_credit_yes);
        System.out.println("不买+credit:"+num_credit_no);
        //// 概率判断
        // 买的概率
        double buy_yes2=buy_yes*1.0/data_length;
        // 不买的概率
        double buy_no2=buy_no*1.0/data_length;
        System.out.println("训练数据中买的概率:"+buy_yes2);
        System.out.println("训练数据中不买的概率:"+buy_no2);
        /// 未知用户的判断
        double nb_buy_yes=(1.0*num_age_yes/buy_yes)*(1.0*num_income_yes/buy_yes)*(1.0*num_student_yes/buy_yes)*(1.0*num_credit_yes/buy_yes)*buy_yes2;
        double nb_buy_no=(1.0*num_age_no/buy_no)*(1.0*num_income_no/buy_no)*(1.0*num_student_no/buy_no)*buy_no2*(1.0*num_credit_no/buy_no);
        System.out.println("新用户买的概率:"+nb_buy_yes);
        System.out.println("新用户不买的概率:"+nb_buy_no);
        if(nb_buy_yes>nb_buy_no){
            System.out.println("新用户买的概率大");
        }else {
            System.out.println("新用户不买的概率大");
        }

    }

    private static void testData(int age,String a,String b,String c) {

        for (JavaBean bb : datas) {
            if (bb.getBuys_computer().equals("Yes")) {
                buy_yes++;
                if (bb.getIncome().equals(a)) {
                    num_income_yes++;
                }
                if (bb.getStudent().equals(b)) {
                    num_student_yes++;
                }
                if (bb.getCredit_rating().equals(c)) {
                    num_credit_yes++;
                }
                if (bb.getAge() == age) {
                    num_age_yes++;
                }
            } else {
                //No
                buy_no++;
                if (bb.getIncome().equals(a)) {
                    num_income_no++;
                }
                if (bb.getStudent().equals(b)) {
                    num_student_no++;
                }
                if (bb.getCredit_rating().equals(c)) {
                    num_credit_no++;
                }
                if (bb.getAge() == age) {
                    num_age_no++;
                }
            }
        }
    }

    public static void getData() {
        RandomAccessFile file =null;
        try {
            file= new RandomAccessFile("src\\main\\java\\xyz\\hujf\\bayes\\test1\\test.txt","rw");
            String str = null;
            while ((str= file.readLine())!=null){
                //调用clear()方法或者compact()方法
                split(str);
                data_length++;
            }
        } catch (Exception e) {
            throw  new RuntimeException("emmmmm 出错了");
        }finally {
            try {
                file.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static void split(String s) {
        String[] sx = s.split("\t");
        JavaBean bean=new JavaBean(Integer.parseInt(sx[0]), sx[1], sx[2], sx[3], sx[4]);
        datas.add(bean);
    }
}
